home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1990,1991,1992 Chris and John Downey */
- #ifndef lint
- static char *sccsid = "@(#)mouse.c 2.1 (Chris & John Downey) 7/29/92";
- #endif
-
- /***
-
- * program name:
- xvi
- * function:
- PD version of UNIX "vi" editor, with extensions.
- * module name:
- mouse.c
- * module function:
- Machine-independent mouse interface routines.
- * history:
- STEVIE - ST Editor for VI Enthusiasts, Version 3.10
- Originally by Tim Thompson (twitch!tjt)
- Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
- Heavily modified by Chris & John Downey
- ***/
-
- #include "xvi.h"
-
- /*
- * Find the Line corresponding to a given physical screen row.
- *
- * Also return (in *pstartrow) the physical screen row on which that
- * Line starts.
- */
- static Line *
- findline(wp, row, pstartrow)
- Xviwin *wp;
- register int row;
- int *pstartrow;
- {
- register int lposn;
- int maxrow;
- register Line *lp;
- Line *lastline;
-
- lp = wp->w_topline;
- lastline = wp->w_buffer->b_lastline;
- lposn = wp->w_winpos;
- maxrow = wp->w_cmdline;
-
- for (;;) {
- register int newposn;
-
- newposn = lposn + LONG2INT(plines(wp, lp));
- if (
- (
- /*
- * If we've found the right line ...
- */
- row >= lposn
- &&
- row < newposn
- )
- ||
- (
- /*
- * ... or we've got to the end of the buffer ...
- */
- lp->l_next == wp->w_buffer->b_lastline
- )
- ||
- (
- /*
- * ... or we're at the bottom of the window ...
- */
- newposn >= maxrow
- )
- ) {
- /*
- * ... we return this line.
- */
- *pstartrow = lposn;
- return lp;
- }
- lposn = newposn;
- lp = lp->l_next;
- }
- }
-
- /*
- * Move the text cursor as near as possible to the given physical
- * screen co-ordinates.
- */
- static void
- setcursor(wp, row, col)
- Xviwin *wp;
- int row; /* row where mouse was clicked */
- int col; /* column where mouse was clicked */
- {
- int startrow; /* row at which line starts */
- int vcol; /* virtual column */
- Line *lp; /* logical line corresponding to row */
-
- lp = findline(wp, row, &startrow);
- vcol = col + ((row - startrow) * wp->w_ncols);
- move_cursor(wp, lp, 0);
- coladvance(wp, (wp->w_curswant = vcol));
- }
-
- /*
- * Find the window a given physical screen row is in.
- */
- static Xviwin *
- findwin(row)
- register int row;
- {
- register Xviwin *wp;
-
- wp = curwin;
- for (;;) {
- if (wp->w_winpos <= row && row <= wp->w_cmdline) {
- /*
- * We've found the right window.
- */
- return wp;
- }
- if ((wp = next_window(wp)) == curwin) {
- /*
- * This can't happen: the mouse isn't in any
- * window.
- */
- return NULL;
- }
- }
- }
-
- /*
- * Handle mouse drag event.
- */
- void
- mousedrag(row1, row2, col1, col2)
- int row1, row2, col1, col2;
- {
- if (State == NORMAL && row1 != row2 && row1 < Rows - 1) {
- Xviwin *wp;
-
- if ((wp = findwin(row1)) == NULL) {
- /*
- * This can't happen.
- */
- return;
- }
-
- if (wp->w_cmdline == row1) {
- unsigned savecho;
-
- savecho = echo;
- echo &= ~e_CHARUPDATE;
-
- (void) move_sline(wp, row2 - row1);
-
- echo = savecho;
-
- move_cursor_to_window(curwin);
- update_all();
- cursupdate(curwin);
- wind_goto(curwin);
- }
- }
- }
-
- /*
- * This function is called by the (obviously machine-dependent) mouse
- * event handling code when a mouse button is pressed & released.
- *
- * The algorithm we use here is semantically complicated, but seems to
- * be fairly intuitive in actual use.
- */
- void
- mouseclick(row, col)
- register int row; /* row the mouse cursor is in */
- int col; /* column the mouse cursor is in */
- {
- register Xviwin *wp;
-
- if (State != NORMAL) {
- return;
- }
-
- /*
- * First find which window the mouse is in.
- */
- if ((wp = findwin(row)) == NULL) {
- /*
- * This can't happen.
- */
- return;
- }
-
- if (wp != curwin) {
- /*
- * The window the mouse is in isn't the current window.
- * Make it the current window.
- */
- curwin = wp;
- curbuf = wp->w_buffer;
- }
-
- if (row == wp->w_cmdline) {
- /*
- * If the mouse is on the status line of any window,
- * we update the information on the status line. This
- * applies whether or not it was already the current
- * window.
- */
- show_file_info(wp);
- } else {
- /*
- * Move the cursor as near as possible to where the
- * mouse was clicked.
- */
- setcursor(wp, row, col);
-
- /*
- * If the window has at least 2 text rows, and ...
- */
- if (wp->w_nrows > 2) {
- if (row == wp->w_winpos) {
- /*
- * ... we're on the top line of the
- * window - scroll down ...
- */
- scrolldown(wp, (unsigned) 1);
- update_window(wp);
- } else if (row == wp->w_cmdline - 1) {
- /*
- * ... or we're on the bottom line of
- * the window - scroll up ...
- */
- scrollup(wp, (unsigned) 1);
- update_window(wp);
- }
- }
- }
-
- /*
- * Make sure physical screen and cursor position are updated.
- */
- cursupdate(wp);
- wind_goto(wp);
- }
-